#include "resourcemanager.h"
#include "qwebsecurityorigin.h"
#include "qfile.h"
#include "qfileinfo.h"
#include "qfileiconprovider.h"
#include "qbuffer.h"
#include "qdir.h"
#include "qdebug.h"

void ResourceManager::requestIcon(QString filePath, int iconSize, NetworkReply *reply) {
	reply->setHttpStatusCode(200, "Ok");
	reply->setContentType("image/png");
	QFileIconProvider* fileIconProvider = new QFileIconProvider();
	QIcon fileIcon = fileIconProvider->icon(filePath);
	delete fileIconProvider;
	QByteArray byteArray;
	QBuffer buffer(&byteArray);
	fileIcon.pixmap(iconSize, iconSize).save(&buffer, "png");
	buffer.deleteLater();
	reply->setContent(byteArray);
}

QImage ResourceManager::brightness(QImage image, int bgt)
{
	int x, y;
	for(y=0;y<image.height();y++)
		for(x=0;x<image.width();x++)
		{
			int r=qRed(image.pixel(x, y))+bgt;
			int g=qGreen(image.pixel(x, y))+bgt;
			int b=qBlue(image.pixel(x, y))+bgt;

			if(r>255)
				r=255;
			if(r<0)
				r=0;
			if(g>255)
				g=255;
			if(g<0)
				g=0;
			if(b>255)
				b=255;
			if(b<0)
				b=0;

			image.setPixel(x, y, QColor(r, g, b).rgb());
		}
	return image;
}

void ResourceManager::requestFile(QString filePath, QHash<QString, QString>params, NetworkReply* reply) {
	QFile fileRef(filePath);
	if (!fileRef.open(QIODevice::ReadOnly)) return;

	QString contentType = "application/octet-stream";

	if (filePath.endsWith(".xml")) {
		contentType = "text/xml";
	} else if (filePath.endsWith(".html")) {
		contentType = "text/html";
	} else if (filePath.endsWith(".css")) {
		contentType = "text/css";
	} else if (filePath.endsWith(".png")) {
		contentType = "image/png";
	} else if (filePath.endsWith(".js")) {
		contentType = "text/javascript";
	}

	QByteArray byteArray = fileRef.readAll();
	if (contentType.startsWith("image/")) {
		if (params.contains("filter-brightness")) {
			int value = QVariant(params["filter-brightness"]).toInt();
			QPixmap pixmap;
			//qDebug() <<
				pixmap.loadFromData(byteArray);
			QImage image = pixmap.toImage();
			QImage alpha = image.alphaChannel();
			image = 	this->brightness(image, value);
			image.setAlphaChannel(alpha);
			pixmap = pixmap.fromImage(image);
			QBuffer buffer(&byteArray);
			buffer.open(QIODevice::WriteOnly);
			pixmap.save(&buffer, "PNG");
		}
	}

	reply->setHttpStatusCode(200, "Ok");
	reply->setContentType(contentType);
	reply->setContent(byteArray);
	fileRef.close();
}

void ResourceManager::requestDir(QString dirPath, NetworkReply* reply) {
	reply->setHttpStatusCode(200, "Ok");
	reply->setContentType("text/xml; charset=UTF-8");
	QString responseText = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
	QFileInfo fileInfo(dirPath);
	QString absolutePath = fileInfo.absoluteFilePath();
	QDir absoluteDir(absolutePath);
	QDir::Filters filter = (QDir::AllEntries | QDir::NoDotAndDotDot);
	QDir::SortFlags sortFlags = (QDir::DirsFirst);
	QFileInfoList fileInfoList = absoluteDir.entryInfoList(filter, sortFlags);
	int fileInfoLength = fileInfoList.length();
	if (fileInfoLength) {
		responseText += "<root>";
		for (int i = 0; i < fileInfoLength; i++) {
			QFileInfo fileInfo = fileInfoList.at(i);
			QString path = fileInfo.absoluteFilePath();
			path.prepend("file://");
			QString type = (fileInfo.isDir() ? "dir" : "file");
			responseText += "<entry type=\""+type+"\" path=\""+path+"\" />";
		}
		responseText += "</root>";
	} else responseText += "<root />";
	reply->setContent(responseText);
}

NetworkReply *ResourceManager::createRequest(QUrl requestUrl) {
	NetworkReply* networkReply = new NetworkReply();
	networkReply->setHttpStatusCode(404, "Not Found");

	QString requestScheme = requestUrl.scheme();
	QString requestPath = requestUrl.path();

	if (requestScheme == "res") {
		requestScheme = this->documentRoot.scheme();
		requestPath.prepend(this->documentRoot.path());
	}

	QHash<QString, QString> requestParams;
	QList<QPair<QString, QString> > queryParams = requestUrl.queryItems();
	for (int i = 0; i < queryParams.length(); i++) {
		QPair<QString, QString> keyValue = queryParams.at(i);
		requestParams[keyValue.first] = keyValue.second;
	}

	if (requestScheme == "file") {
		QFileInfo fileInfo(requestPath);
		if (fileInfo.exists() or fileInfo.isReadable()) {
			QString requestType = requestParams["type"];
			if (requestType == "icon") {
				int iconSize = QVariant(requestParams["size"]).toInt();
				if (iconSize <= 0) iconSize = 16;
				this->requestIcon(requestPath, iconSize, networkReply);
			} else if (fileInfo.isFile()) {
				this->requestFile(requestPath, requestParams, networkReply);
			} else if (fileInfo.isDir()) {
				this->requestDir(requestPath, networkReply);
			}
		}
	} else {
		qDebug() << "WTF?" << requestScheme;
	}

	networkReply->deleteLater();
	return networkReply;

}

ResourceManager::ResourceManager(QApplication* application) {
	this->application = application;

	QStringList localSchemes = QWebSecurityOrigin::localSchemes();
	for (int c = 0; c < localSchemes.length(); c++) {
		QWebSecurityOrigin::removeLocalScheme(localSchemes.at(c));
	}
	QWebSecurityOrigin::addLocalScheme("res");
	QWebSecurityOrigin::addLocalScheme("file");

	this->documentRoot = QUrl(application->applicationFilePath());
	this->documentRoot = this->documentRoot.resolved(QUrl("../Resources/web/"));
	if (!QFile(this->documentRoot.toString()).exists()) {
		this->documentRoot = QUrl(DOCUMENT_ROOT);
	}
	if (this->documentRoot.scheme().isEmpty()) {
		this->documentRoot.setScheme("file");
	}
}
